class RTCClass {
    constructor(videoDom, userId, targetUid, socket, localStream = null) {
        // 保存sdp
        this.offer;
        this.answer;

        this.userId = userId;
        // 建立通信目标id，一个单点对点
        this.targetUid = targetUid;

        // 保存候选地址
        this.candidateList = [];
        // 如果两台服务器无法点对点连接，则会使用中继服务器来通信
        this.rtcPcParams = {
            iceServers: [
                { urls: "stun:stun.l.google.com:19302" }, // STUN服务器
                {
                    urls: "turn:www.kairos-k.cn:3478", // TURN服务器的URL
                    username: "yxx",              // TURN服务器的用户名
                    credential: "yxx"           // TURN服务器的密码
                }
            ],
        };

        this.socket = socket;
        // rtc连接对象
        this.rtcConnection = this.createRtcConnection();

        // 如果初始化不为空，发送自身的本地流
        if (localStream && Object.keys(localStream) && localStream.active) {
            this.addLocalStreamToRtcConnection(localStream);
        }

        // 接收到流时展示的盒子
        this.onTrack(videoDom);
    }

    // 创建RTC连接
    createRtcConnection(socket) {
        this.rtcConnection = new RTCPeerConnection(this.rtcPcParams);
        this.onicecandidate(socket);
        this.oniceconnectionstatechange();
        console.log("rtc创建成功", this.rtcConnection);
        return this.rtcConnection;
    }

    // 定义获取候选地址时的逻辑，发起者创建offer时会触发，接受者设置远程描述后创建answer时会触发，以及内网连接失败后会尝试NAT穿透和使用TURN服务器时会触发
    onicecandidate() {
        // 存储自身候选地址
        this.rtcConnection.onicecandidate = (e) => {
            let candidate = e.candidate;
            if (candidate) {
                this.candidateList.push(candidate);
                // 有新的ICE地址时广播出去
                let sendObj = JSON.stringify({
                    type: "candidate",
                    targetUid: this.targetUid,
                    userId: this.userId,
                    candidate: candidate,
                });
                console.log("发送候选地址------", this.candidateList)
                this.socket.send(sendObj);
            }
        };
    }

    // rtc状态改变时回调
    oniceconnectionstatechange() {
        this.rtcConnection.oniceconnectionstatechange = () => {
            console.log("rtc当前状态为：", this.rtcConnection.iceConnectionState);
        }
    }

    // 处理onTrack回调，接收到远程的媒体流时触发
    onTrack(videoDom) {
        this.rtcConnection.ontrack = (e) => {
            console.log(e.streams);
            console.log("rtc接收到了远程媒体流");
            videoDom.srcObject = e.streams[0];
        };
    }

    // 创建offer，创建会话描述协议sdp，双方需要互相交换sdp
    createOffer = async () => {
        let sdp = await this.rtcConnection.createOffer({
            offerToReceiveVideo: true,
            offerToReceiveAudio: true,
        })
        // 存储sdp
        this.offer = sdp;
        console.log("offer的sdp为", JSON.stringify(sdp));
        this.rtcConnection.setLocalDescription(sdp);
        return sdp;
    }

    // 创建Answer
    createAnswer = async () => {
        let sdp = await this.rtcConnection.createAnswer({
            offerToReceiveVideo: true,
            offerToReceiveAudio: true,
        });
        this.answer = sdp;
        console.log("answer的sdp为", JSON.stringify(sdp));
        this.rtcConnection.setLocalDescription(sdp);
        return sdp;
    }

    // 设置远程描述
    setRemoteDescription(currentText) {
        const remoteSdp = JSON.parse(currentText);
        this.rtcConnection.setRemoteDescription(
            new RTCSessionDescription(remoteSdp)
        );
        console.log("设置远程描述成功", remoteSdp);
    }

    // 添加候选地址
    addCandidate(currentText) {
        let candidate = JSON.parse(currentText);
        this.rtcConnection.addIceCandidate(new RTCIceCandidate(candidate));
        console.log("添加候选成功", candidate);
    }

    // 将本地视频流添加到RTC中
    addLocalStreamToRtcConnection(localStream) {
        try {
            localStream.getTracks().forEach((track) => {
                this.rtcConnection.addTrack(track, localStream);
            });
            console.log("将本地视频流添加到RTC连接成功");
        } catch (error) {
            console.error("将本地视频流添加到RTC连接失败:", error);
        }
    }
}


export default RTCClass;